package com.personal.dao.bean;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

import com.personal.dao.enums.CriteriaTypeEnum;

/**
 * 条件
 * @author cuibo
 *
 */
public class Criteria implements Serializable
{
    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    protected List<Criterion> criteria;

    public Criteria()
    {
        super();
        criteria = new ArrayList<Criterion>();
    }
    
    public Criteria andSqlCondition(String condition, Object... values)
    {
        Criterion criterion = new Criterion();
        criterion.operator = condition;
        criterion.value = values;
        criterion.type = CriteriaTypeEnum.自定义条件;
        criteria.add(criterion);
        return (Criteria) this;
    }

    public Criteria andFieldIsNull(String fieldName)
    {
        Criterion criterion = new Criterion();
        criterion.fieldName = fieldName;
        criterion.operator = " is null ";
        criterion.type = CriteriaTypeEnum.无值条件;
        criteria.add(criterion);
        return (Criteria) this;
    }

    public Criteria andFieldIsNotNull(String fieldName)
    {
        Criterion criterion = new Criterion();
        criterion.fieldName = fieldName;
        criterion.operator = " is not null ";
        criterion.type = CriteriaTypeEnum.无值条件;
        criteria.add(criterion);
        return (Criteria) this;
    }

    public Criteria andFieldEqualTo(String fieldName, Object value)
    {
        Criterion criterion = new Criterion();
        criterion.fieldName = fieldName;
        criterion.operator = " = ";
        criterion.value = value;
        criterion.type = CriteriaTypeEnum.单值条件;
        criteria.add(criterion);
        return (Criteria) this;
    }

    public Criteria andFieldNotEqualTo(String fieldName, Object value)
    {
        Criterion criterion = new Criterion();
        criterion.fieldName = fieldName;
        criterion.operator = " <> ";
        criterion.value = value;
        criterion.type = CriteriaTypeEnum.单值条件;
        criteria.add(criterion);
        return (Criteria) this;
    }

    public Criteria andFieldGreaterThan(String fieldName, Object value)
    {
        Criterion criterion = new Criterion();
        criterion.fieldName = fieldName;
        criterion.operator = " > ";
        criterion.value = value;
        criterion.type = CriteriaTypeEnum.单值条件;
        criteria.add(criterion);
        return (Criteria) this;
    }

    public Criteria andFieldGreaterThanOrEqualTo(String fieldName, Object value)
    {
        Criterion criterion = new Criterion();
        criterion.fieldName = fieldName;
        criterion.operator = " >= ";
        criterion.value = value;
        criterion.type = CriteriaTypeEnum.单值条件;
        criteria.add(criterion);
        return (Criteria) this;
    }

    public Criteria andFieldLessThan(String fieldName, Object value)
    {
        Criterion criterion = new Criterion();
        criterion.fieldName = fieldName;
        criterion.operator = " < ";
        criterion.value = value;
        criterion.type = CriteriaTypeEnum.单值条件;
        criteria.add(criterion);
        return (Criteria) this;
    }

    public Criteria andFieldLessThanOrEqualTo(String fieldName, Object value)
    {
        Criterion criterion = new Criterion();
        criterion.fieldName = fieldName;
        criterion.operator = " <= ";
        criterion.value = value;
        criterion.type = CriteriaTypeEnum.单值条件;
        criteria.add(criterion);
        return (Criteria) this;
    }

    public Criteria andFieldLike(String fieldName, Object value)
    {
        Criterion criterion = new Criterion();
        criterion.fieldName = fieldName;
        criterion.operator = " like ";
        criterion.value = value;
        criterion.type = CriteriaTypeEnum.单值条件;
        criteria.add(criterion);
        return (Criteria) this;
    }

    public Criteria andFieldNotLike(String fieldName, Object value)
    {
        Criterion criterion = new Criterion();
        criterion.fieldName = fieldName;
        criterion.operator = " not like ";
        criterion.value = value;
        criterion.type = CriteriaTypeEnum.单值条件;
        criteria.add(criterion);
        return (Criteria) this;
    }

    public Criteria andFieldIn(String fieldName, Collection<Object> values)
    {
        Criterion criterion = new Criterion();
        criterion.fieldName = fieldName;
        criterion.operator = " in ";
        criterion.value = values;
        criterion.type = CriteriaTypeEnum.多个范围值条件;
        criteria.add(criterion);
        return (Criteria) this;
    }

    public Criteria andFieldNotIn(String fieldName, Collection<Object> values)
    {
        Criterion criterion = new Criterion();
        criterion.fieldName = fieldName;
        criterion.operator = " not in ";
        criterion.value = values;
        criterion.type = CriteriaTypeEnum.多个范围值条件;
        criteria.add(criterion);
        return (Criteria) this;
    }
    
    public Criteria andFieldIn(String fieldName, Object... values)
    {
        Criterion criterion = new Criterion();
        criterion.fieldName = fieldName;
        criterion.operator = " in ";
        List<Object> list = new ArrayList<>();
        Collections.addAll(list, values);
        criterion.value = list;
        criterion.type = CriteriaTypeEnum.多个范围值条件;
        criteria.add(criterion);
        return (Criteria) this;
    }

    public Criteria andFieldNotIn(String fieldName, Object... values)
    {
        Criterion criterion = new Criterion();
        criterion.fieldName = fieldName;
        criterion.operator = " not in ";
        List<Object> list = new ArrayList<>();
        Collections.addAll(list, values);
        criterion.value = list;
        criterion.type = CriteriaTypeEnum.多个范围值条件;
        criteria.add(criterion);
        return (Criteria) this;
    }

    public Criteria andFieldBetween(String fieldName, Object value1, Object value2)
    {
        Criterion criterion = new Criterion();
        criterion.fieldName = fieldName;
        criterion.operator = " between ";
        criterion.value = value1;
        criterion.secondValue = value2;
        criterion.type = CriteriaTypeEnum.前后范围值条件;
        criteria.add(criterion);
        return (Criteria) this;
    }

    
    public Criteria andFieldNotBetween(String fieldName, Object value1, Object value2)
    {
        Criterion criterion = new Criterion();
        criterion.fieldName = fieldName;
        criterion.operator = " not between ";
        criterion.value = value1;
        criterion.secondValue = value2;
        criterion.type = CriteriaTypeEnum.前后范围值条件;
        criteria.add(criterion);
        return (Criteria) this;
    }
    

    public boolean isValid()
    {
        return criteria.size() > 0;
    }

    public List<Criterion> getCriteria()
    {
        return criteria;
    }

    /**
     * 条件
     * @author cuibo
     *
     */
    public static class Criterion implements Serializable
    {
        /**
         * 
         */
        private static final long serialVersionUID = 7770923418144501216L;

        /** 属性名 */
        private String fieldName;

        /** 条件 */
        private String operator;

        /** 值 */
        private Object value;

        /** 第二个值 */
        private Object secondValue;
        
        /** 条件类型 */
        private CriteriaTypeEnum type;

        /** 类型处理 */
        private String typeHandler;

        public String getFieldName()
        {
            return fieldName;
        }

        public Object getValue()
        {
            return value;
        }

        public Object getSecondValue()
        {
            return secondValue;
        }

        public String getTypeHandler()
        {
            return typeHandler;
        }

        public CriteriaTypeEnum getType()
        {
            return type;
        }

        public String getOperator()
        {
            return operator;
        }

    }
}
